package com.dxb.test.forkjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

public class CustomRecursiveAction extends RecursiveAction {

    private static AtomicInteger i = new AtomicInteger(0);

    private String workload = "";
    private static final int THRESHOLD = 4;

    private static Logger logger = Logger.getAnonymousLogger();

    public CustomRecursiveAction(String workload) {
        this.workload = workload;
    }

    @Override
    protected void compute() {
        if (workload.length() > THRESHOLD) {
            ForkJoinTask.invokeAll(createSubtasks());
        } else {
            processing(workload);
        }
    }

    private List<CustomRecursiveAction> createSubtasks() {
        List<CustomRecursiveAction> subtasks = new ArrayList<>();

        String partOne = workload.substring(0, workload.length() / 2);
        String partTwo = workload.substring(workload.length() / 2);

        subtasks.add(new CustomRecursiveAction(partOne));
        subtasks.add(new CustomRecursiveAction(partTwo));

        return subtasks;
    }

    private void processing(String work) {
        i.incrementAndGet();
        String result = work.toUpperCase();
        logger.info("This result - (" + result + ") - was processed by "
                + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        CustomRecursiveAction action = new CustomRecursiveAction("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
        //submit() 或 execute() 方法
        //这两个方法的调用方式是相同的
        //forkJoinPool.execute(action);
        //forkJoinPool.submit(action);
        // 用于触发任务的执行,返回任务执行的结果
        //action.join();
        //使用 invoke() 方法 fork 任务并等待结果，不需要任何手动连接 ( join )
        forkJoinPool.invoke(action);
        System.out.println("fork:" + i.get());
        forkJoinPool.shutdown();
    }
}
